package com.lemon.conf;

import java.sql.SQLException;
import java.util.Date;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.io.VFS;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.util.JdbcConstants;
import com.github.pagehelper.PageHelper;
import com.lemon.conf.content.IdTypeHandler;
import com.lemon.conf.content.IdTypeNullHandler;
import com.lemon.utils.StringUtil;

@Configuration  
public class DruidDBConfig {  
    private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);  
    /*@Autowired
    private Environment env;
    */
    @Value("${spring.datasource.url}")  
    private String dbUrl;  
      
    @Value("${spring.datasource.username}")  
    private String username;  
      
    @Value("${spring.datasource.password}")  
    private String password;  
      
    @Value("${spring.datasource.driver-class-name}")  
    private String driverClassName;  
      
    @Value("${spring.datasource.initialSize}")  
    private int initialSize;  
      
    @Value("${spring.datasource.minIdle}")  
    private int minIdle;  
      
    @Value("${spring.datasource.maxActive}")  
    private int maxActive;  
      
    @Value("${spring.datasource.maxWait}")  
    private int maxWait;  
      
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")  
    private int timeBetweenEvictionRunsMillis;  
      
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")  
    private int minEvictableIdleTimeMillis;  
      
    @Value("${spring.datasource.validationQuery}")  
    private String validationQuery;  
      
    @Value("${spring.datasource.testWhileIdle}")  
    private boolean testWhileIdle;  
     
    @Value("${spring.datasource.testOnBorrow}")  
    private boolean testOnBorrow;  
      
    @Value("${spring.datasource.testOnReturn}")  
    private boolean testOnReturn;  
      
    @Value("${spring.datasource.poolPreparedStatements}")  
    private boolean poolPreparedStatements;  
      
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")  
    private int maxPoolPreparedStatementPerConnectionSize;  
      
    @Value("${spring.datasource.filters}")  
    private String filters;  
      
    @Value("${spring.datasource.connectionProperties}")  
    private String connectionProperties;  
    
    
    
    
    
    
    
	@Bean(name = "dataSource") // 声明其为Bean实例
    @Primary  //在同样的DataSource中，首先使用被标注的DataSource  
    public DataSource dataSource(){  
		DruidDataSource datasource = new DruidDataSource();
		System.out.println("------------------");
		datasource.setUrl(this.dbUrl);
		datasource.setUsername(username);
		datasource.setPassword(password);
		datasource.setDriverClassName(driverClassName);
		datasource.setDbType(JdbcConstants.MYSQL);

		// configuration
		datasource.setInitialSize(initialSize);
		datasource.setMinIdle(minIdle);
		datasource.setMaxActive(maxActive);
		datasource.setMaxWait(maxWait);
		datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		datasource.setValidationQuery(validationQuery);
		datasource.setTestWhileIdle(testWhileIdle);
		datasource.setTestOnBorrow(testOnBorrow);
		datasource.setTestOnReturn(testOnReturn);
		datasource.setPoolPreparedStatements(poolPreparedStatements);
		datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
		try {
			datasource.setFilters(filters);
		} catch (SQLException e) {
			logger.error("druid configuration initialization filter", e);
		}
		datasource.setConnectionProperties(connectionProperties);

		return datasource;
	}

	@Value("${pagehelper.helperDialect}")
	private String helperDialect;
	@Value("${pagehelper.params}")
	private String params;
	@Value("${pagehelper.reasonable}")
	private String reasonable;

	@Bean(name = "pageHelper")
	public PageHelper pageHelper() {
		System.out.println("MyBatisConfiguration.pageHelper()");
		PageHelper pageHelper = new PageHelper();
		Properties p = new Properties();
		p.setProperty("offsetAsPageNum", "true");
		p.setProperty("rowBoundsWithCount", "true");
		p.setProperty("reasonable", reasonable);
		p.setProperty("dialect", helperDialect);
		p.setProperty("params", params);
		pageHelper.setProperties(p);
		System.out.println(
				"========== pagehelper init success " + StringUtil.DateToString(new Date(), 41) + "  ============");
		return pageHelper;
	}

	@Value("${mybatis.type-aliases-package}")
	private String aliases;
	@Value("${myYml.start-state}")
	private String sstate;

	@Bean("mysqlSqlSessionFactory")
	public SqlSessionFactory mysqlSqlSessionFactory() throws Exception {
		SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
		sqlSessionFactory.setDataSource(dataSource() );

		VFS.addImplClass(SpringBootVFS.class);
		// IMPORTANT: we MUST set the 'VFS',
		// otherwise if you run this project as a 'executable jar', then mybatis will
		// throw an exception saying that it can not find java POJO
		sqlSessionFactory.setVfs(VFS.class);
		sqlSessionFactory.setTypeAliasesPackage(aliases);

		Interceptor[] plugins = new Interceptor[] { pageHelper() };
		sqlSessionFactory.setPlugins(plugins);

		if (sstate.equals("debug")) {
			sqlSessionFactory.setTypeAliases(new Class<?>[] { IdTypeNullHandler.class }); // 测试不需要混淆的
		} else {
			sqlSessionFactory.setTypeAliases(new Class<?>[] { IdTypeHandler.class }); // 线上正式文件
		}

		System.out.println("========== VFS init success " + StringUtil.DateToString(new Date(), 41) + "  ============");
		return sqlSessionFactory.getObject();
	}

//	@Bean
//	public MapperScannerConfigurer mapperScannerConfigurer() {
//		MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
//		mapperScannerConfigurer.setSqlSessionFactoryBeanName("mysqlSqlSessionFactory");
//		mapperScannerConfigurer.setBasePackage("com.lemon.baseMapper");
//		Properties properties = new Properties();
//		// 这里要特别注意，不要把MyMapper放到 basePackage 中，也就是不能同其他Mapper一样被扫描到。
//		properties.setProperty("mappers", BaseMapper.class.getName());
//		properties.setProperty("notEmpty", "false");
//		properties.setProperty("IDENTITY", "MYSQL");
//		mapperScannerConfigurer.setProperties(properties);
//		return mapperScannerConfigurer;
//	}
   
}  
